// crankit.cpp

// 2008-04-21 21:24:52 (Jake): created

#include "crankit_precompiled.h"

#include <iostream>

#include "game.h"
#include "gamecameramanipulator.h"
#include "headsupdisplay.h"
#include "song.h"
#include "songrenderer.h"
#include "songplayer.h"

using namespace std;

string Level::toString(int d) 
{
	switch (d) {
		case Amazing: return "Amazing";
		case Medium: return "Medium";
		case Easy: return "Easy";
		case SupaEasy: return "SupaEasy";
	}

	throw std::runtime_error("Level::toString(): Unknown difficulty");

	return "unknown";
}

Game::Game() : _time(0), _level(Level::Medium)
{

}

void testSongRenderer()
{
	string path = "C:/Private/Games/FretsOnFire/data/songs/bangbang/";

	osg::ref_ptr<Game> game = new Game();
	osg::ref_ptr<Song> song = new Song(path);

	game->setSong(song.get());
	game->setLevel(Level::Easy);

	try {
		song->loadNotes();

		SongRenderer songRenderer(game.get());
		osg::ref_ptr<osg::Node> notesNode = songRenderer.renderNotes();

		osgDB::writeNodeFile(*notesNode.get(), "notes.osg");
	}
	catch (std::exception& e) {
		cerr << "error: " << e.what() << endl;
	}
}

void testSong()
{
	string path = "C:/Private/Games/FretsOnFire/data/songs/bangbang/";

	Song song(path);

	try {
		song.loadNotes();

		SongNotes& notes = song.getNotes();
		for (SongNotes::const_iterator iter = notes.begin();
			iter != notes.end(); 
			++iter)
		{
			const SongNote& note = *iter;
			cout << "t " << note.time << " l " << note.level
				<< " b " << note.band << " t " << note.type
				<< " len " << note.length << endl;
		}

		const SongTempoList& tempoList = song.getTempoList();
		for (SongTempoList::const_iterator iter = tempoList.begin();
			iter != tempoList.end(); 
			++iter)
		{
			const SongTempo& tempo = *iter;
			cout << "time " << tempo.time
				<< " tempo " << tempo.tempo << endl;
		}

	}
	catch (std::exception& e) {
		cerr << "error: " << e.what() << endl;
	}
}

void testViewer()
{
	string path = "C:/Private/Games/FretsOnFire/data/songs/bangbang/";

	osg::ref_ptr<Game> game = new Game();
	osg::ref_ptr<Song> song = new Song(path);

	song->loadNotes();

	SongRenderer songRenderer(game.get());

	game->setSong(song.get());
	game->setLevel(Level::Easy);

	osg::ref_ptr<osg::Node> notesNode = songRenderer.renderNotes();
	osg::ref_ptr<osg::Node> barsNode = songRenderer.renderBars();

	osg::ref_ptr<HeadsUpDisplay> headsUpDisplay = new HeadsUpDisplay(game.get());

	osg::ref_ptr<osg::Group> sceneNode = new osg::Group();
	sceneNode->addChild(notesNode.get());
	sceneNode->addChild(barsNode.get());
	sceneNode->addChild(headsUpDisplay->getNode());

	osg::ref_ptr<osgViewer::CompositeViewer> viewer = new osgViewer::CompositeViewer();

	osg::ref_ptr<osgViewer::View> mainView = new osgViewer::View();
	osg::Camera* camera = mainView->getCamera();
	game->setCamera(camera);
//	camera->setUpdateCallback(new CameraUpdateCallback(game.get()));
	camera->setAllowEventFocus(true);
	GameCameraManipulator* manipulator = new GameCameraManipulator(game.get());
//	mainView->setCameraManipulator(manipulator);
	mainView->setCameraManipulator(new osgGA::TrackballManipulator());

	float pos = -3;
	osg::Vec3 center(0, pos+3, 0);
	osg::Vec3 eye(0, pos, 0.8);
	osg::Vec3 up(0, 0, 1);

	mainView->getCameraManipulator()->setHomePosition(eye, center, up);
	mainView->setSceneData(sceneNode.get());
	mainView->setUpViewInWindow(20, 20, 640, 480);

	viewer->addView(mainView.get());

	SongPlayer player;

	player.load(song.get());
	player.play();

	int result = viewer->run();

	player.stop();
}

void testPlayer()
{
	string path = "C:/Private/Games/FretsOnFire/data/songs/bangbang/";
	osg::ref_ptr<Song> song = new Song(path);
	osg::ref_ptr<SongPlayer> player = new SongPlayer();
	player->load(song.get());
	player->play();

	cout << "press key to continue" << endl;

	getchar();

	player->pause();

	cout << "press key to continue" << endl;

	getchar();
}

int main(int argc, char** argv)
{
//	testSong();
//	testSongRenderer();
	testViewer();
//	testPlayer();
	
	return 0;
}